package cn.bonoon.services.plugins;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.bonoon.core.IModuleSelected;
import cn.bonoon.core.plugins.FaqCatalogService;
import cn.bonoon.entities.interacting.FaqCatalogEntity;
import cn.bonoon.entities.interacting.FaqReleaseEntity;
import cn.bonoon.kernel.AccessAuthorityResolver;
import cn.bonoon.kernel.events.OperateEvent;
import cn.bonoon.kernel.support.IOperator;
import cn.bonoon.kernel.support.models.Item;
import cn.bonoon.kernel.support.services.AbstractService;

@Service
@Transactional(readOnly = true)
public class FaqCatalogServiceImpl extends AbstractService<FaqCatalogEntity> implements FaqCatalogService{

	@Override
	@Transactional
	public void changeReleaseStatus(IOperator user, Long id) {
		FaqCatalogEntity entity = entityManager.find(FaqCatalogEntity.class, id);
		entity.setDisable(!entity.isDisable());
		entityManager.merge(entity);
	}

	@Override
	public List<Item> releasePlaform(IOperator user, Long id) {
		List<String> selecteds;
		if(null != id && id > 0){
			selecteds = __list(String.class, "select x.key from FaqReleaseEntity x where x.disable=false and x.catalog.id=?", id);
		}else{
			selecteds = Collections.emptyList();
		}
		return AccessAuthorityResolver.valueOf(applicationContext, user).moduleItems(selecteds);
	}

	@Override
	protected FaqCatalogEntity __save(OperateEvent event, FaqCatalogEntity entity) throws Exception {
		FaqCatalogEntity saved = super.__save(event, entity);
		
		for(String key : nonullKeys(event)){
			newRelease(saved, key);
		}
		
		return saved;
	}

	private void newRelease(FaqCatalogEntity saved, String key) {
		FaqReleaseEntity release = new FaqReleaseEntity();
		release.setCatalog(saved);
		release.setDisable(saved.isDisable());
		release.setKey(key);
		entityManager.persist(release);
	}
	
	@Override
	protected FaqCatalogEntity __update(OperateEvent event, FaqCatalogEntity entity) throws Exception {
		List<FaqReleaseEntity> selecteds = new ArrayList<>(__list(FaqReleaseEntity.class, "select x from FaqReleaseEntity x where x.catalog.id=?", entity.getId()));
		NEXT : for(String key : nonullKeys(event)){
			for(FaqReleaseEntity ar : selecteds){
				if(key.equals(ar.getKey())){
					selecteds.remove(ar);
					ar.setDisable(false);
					entityManager.merge(ar);
					continue NEXT;
				}
			}
			
			newRelease(entity, key);
		}
		for(FaqReleaseEntity ar : selecteds){
			ar.setDisable(true);
			entityManager.merge(ar);
		}
		return super.__update(event, entity);
	}
	
	private String[] nonullKeys(OperateEvent event){
		IModuleSelected pe = (IModuleSelected) event.getSource();
		if(pe.getKeys() == null) return new String[0];
		return pe.getKeys();
	}
	@Cacheable(value="common",key="#root.targetClass + #root.methodName+'.'+#key")
	@Override
	public List<FaqCatalogEntity> moduleCatalogs(IOperator user, String key) {
		String ql = "select x.catalog from FaqReleaseEntity x where x.disable=false and x.key=? ";
		ql += "and x.catalog.deleted=false and x.catalog.disable=false ";
		ql += "and (x.catalog.ownerId=0 or x.catalog.ownerId=?) order by x.catalog.ordinal asc";
		return __list(FaqCatalogEntity.class, ql, key, user.getOwnerId());
	}
}
